﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace StrumDiagramMaker
{
    public partial class Form1 : Form
    {
        string versionNumber = "1.0 (Alpha)";

        //Used in saving/loading
        char valueDelimiter = '*';

        StrumPattern StrumPattern = new StrumPattern();

        String PatternString = "1111111111111111";

        List<PictureBox> arrowList = new List<PictureBox>();

        public Form1()
        {
            InitializeComponent();

            string patternsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"Strum Patterns");
            if (!Directory.Exists(patternsFolder))
            {
                Directory.CreateDirectory(patternsFolder);
            }

            openFileDialog.InitialDirectory = patternsFolder;
            saveFileDialog.InitialDirectory = patternsFolder;
        }

        //Reduce flickering on controls.
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                return cp;
            }
        }

        //Update the diagram.
        private void UpdateStrumDiagram()
        {
            //Store the pattern in a string.
            PatternString = StrumPattern.GetPattern(valueDelimiter);

            //Split the pattern into individual 0's and 1's
            string[] patternArray = PatternString.Split(valueDelimiter);

            //Update strum duration. 16th or 8th notes.
            if (StrumPattern.GetStrumDuration() == 8)
                panel_staff.BackgroundImage = Properties.Resources._8thStaff;
            else if (StrumPattern.GetStrumDuration() == 16)
                panel_staff.BackgroundImage = Properties.Resources._16thStaff;

            //Determine whether the + arrow will be pointing up or down. and whether e's and a's are shown.
            Image andArrowImage = null;
            Image eaArrowImage = null;
            if (StrumPattern.GetStrumDuration() == 8)
            {
                andArrowImage = Properties.Resources.UpArrow;
                eaArrowImage = null;
            }
            else if (StrumPattern.GetStrumDuration() == 16)
            {
                andArrowImage = Properties.Resources.DownArrow;
                eaArrowImage = Properties.Resources.UpArrow;
            }

            //Update Time signature:
            if (StrumPattern.GetBeatsPerMeasure() == 3)
                pictureBox_timeSignature.Image = Properties.Resources._3_4;
            else if (StrumPattern.GetBeatsPerMeasure() == 4)
                pictureBox_timeSignature.Image = Properties.Resources._4_4;

            //Update arrows:
            //Beat 1
            if (patternArray[0] == "0")
            {
                pictureBox_1.Image = null;
            }
            else
            {
                pictureBox_1.Image = Properties.Resources.DownArrow;
            }

            if (patternArray[1] == "0")
            {
                pictureBox_1e.Image = null;
            }
            else
            {
                pictureBox_1e.Image = eaArrowImage;
            }

            if (patternArray[2] == "0")
            {
                pictureBox_1and.Image = null;
            }
            else
            {
                pictureBox_1and.Image = andArrowImage;
            }

            if (patternArray[3] == "0")
            {
                pictureBox_1a.Image = null;
            }
            else
            {
                pictureBox_1a.Image = eaArrowImage;
            }

            //Beat 2
            if (patternArray[4] == "0")
            {
                pictureBox_2.Image = null;
            }
            else
            {
                pictureBox_2.Image = Properties.Resources.DownArrow;
            }

            if (patternArray[5] == "0")
            {
                pictureBox_2e.Image = null;
            }
            else
            {
                pictureBox_2e.Image = eaArrowImage;
            }

            if (patternArray[6] == "0")
            {
                pictureBox_2and.Image = null;
            }
            else
            {
                pictureBox_2and.Image = andArrowImage;
            }

            if (patternArray[7] == "0")
            {
                pictureBox_2a.Image = null;
            }
            else
            {
                pictureBox_2a.Image = eaArrowImage;
            }

            //Beat 3
            if (patternArray[8] == "0")
            {
                pictureBox_3.Image = null;
            }
            else
            {
                pictureBox_3.Image = Properties.Resources.DownArrow;
            }

            if (patternArray[9] == "0")
            {
                pictureBox_3e.Image = null;
            }
            else
            {
                pictureBox_3e.Image = eaArrowImage;
            }

            if (patternArray[10] == "0")
            {
                pictureBox_3and.Image = null;
            }
            else
            {
                pictureBox_3and.Image = andArrowImage;
            }

            if (patternArray[11] == "0")
            {
                pictureBox_3a.Image = null;
            }
            else
            {
                pictureBox_3a.Image = eaArrowImage;
            }

            //Beat 4
            if (StrumPattern.GetBeatsPerMeasure() == 4)
            {
                if (patternArray[12] == "0")
                {
                    pictureBox_4.Image = null;
                }
                else
                {
                    pictureBox_4.Image = Properties.Resources.DownArrow;
                }

                if (patternArray[13] == "0")
                {
                    pictureBox_4e.Image = null;
                }
                else
                {
                    pictureBox_4e.Image = eaArrowImage;
                }

                if (patternArray[14] == "0")
                {
                    pictureBox_4and.Image = null;
                }
                else
                {
                    pictureBox_4and.Image = andArrowImage;
                }

                if (patternArray[15] == "0")
                {
                    pictureBox_4a.Image = null;
                }
                else
                {
                    pictureBox_4a.Image = eaArrowImage;
                }
            }

        }

        private void UpdateControls()
        {
            //Update radio buttons.
            //Time Signature
            if (StrumPattern.GetBeatsPerMeasure() == 3)
            {
                radio_ThreeFour.Checked = true;
                radio_FourFour.Checked = false;
            }
            else
            {
                radio_FourFour.Checked = true;
                radio_ThreeFour.Checked = false;
            }

            //StrumDuration.
            if (StrumPattern.GetStrumDuration() == 8)
            {
                radio_Eighth.Checked = true;
                radio_Sixteenth.Checked = false;
            }
            else
            {
                radio_Sixteenth.Checked = true;
                radio_Eighth.Checked = false;
            }

            //Update title and author.
            textBox_title.Text = StrumPattern.GetTitle();
            textBox_author.Text = StrumPattern.GetAuthor();
        }

        //Toggle strum on/off.
        private void arrowClick(object sender, EventArgs e)
        {
            //This is how we access the picturebox arrow that fired the event.
            PictureBox ClickedArrow = (PictureBox)sender;

            StrumPattern.ToggleStrum(ClickedArrow.Name.Replace("pictureBox_", ""));

            UpdateStrumDiagram();
        }

        //Set strum duratation.
        private void strumDurationChanged(object sender, EventArgs e)
        {
            //Set the strumDuration property.
            if (radio_Eighth.Checked == true)
            {
                StrumPattern.SetStrumDuration(8);
            }
            else if (radio_Sixteenth.Checked == true)
            {
                StrumPattern.SetStrumDuration(16);
            }

            //Visually update the diagram.
            UpdateStrumDiagram();
        }

        //Radio buttons time signature changed.
        private void beatsPerMeasureChange(object sender, EventArgs e)
        {
            UpdateTimeSignature();
        }

        private void UpdateTimeSignature()
        {
            //Set the strumPattern value.
            if (radio_FourFour.Checked)
                StrumPattern.SetBeatsPerMeasure(4);
            else
                StrumPattern.SetBeatsPerMeasure(3);

            //Show or hide the last beat. (beat four)
            pictureBox_4.Visible = radio_FourFour.Checked;
            pictureBox_4e.Visible = radio_FourFour.Checked;
            pictureBox_4and.Visible = radio_FourFour.Checked;
            pictureBox_4a.Visible = radio_FourFour.Checked;

            UpdateStrumDiagram();
        }

        //Clear strum pattern
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StrumPattern = new StrumPattern();

            //Reset time signature.
            radio_FourFour.Checked = true;
            radio_ThreeFour.Checked = false;

            //Reset strum duration.
            radio_Sixteenth.Checked = true;
            radio_Eighth.Checked = false;

            //Reset title and author.
            textBox_title.Text = "";
            textBox_author.Text = "";

            UpdateStrumDiagram();
            UpdateControls();
        }

        //Quit
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        //Launch save dialog for pattern
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog.DefaultExt = "strum"; //This value will be checked in File_OK to determine if we are to save a .strum or .png"
            saveFileDialog.Filter = "Strum Patterns (*.strum)|*.strum";

            saveFileDialog.ShowDialog();
        }

        //Launch save dialog for image
        private void exportToImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog.DefaultExt = "png"; //This value will be checked in File_OK to determine if we are to save a .strum or .png"
            saveFileDialog.Filter = "PNG Image (*.png)|*.png";

            saveFileDialog.ShowDialog();
        }

        //Launch open dialog
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog.ShowDialog();
        }

        //Save pattern.
        private void saveFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            string fileName = saveFileDialog.FileName;

            //If the dialogues's default extension property is set to .strum, save a .strum, if its .png save a .png
            if (saveFileDialog.DefaultExt == "strum") //Save a strum file.
            {
                File.WriteAllText(fileName, StrumPattern.GetTitle() + valueDelimiter + StrumPattern.GetAuthor() + valueDelimiter + StrumPattern.GetBeatsPerMeasure() + valueDelimiter + StrumPattern.GetStrumDuration() + valueDelimiter + StrumPattern.GetPattern(valueDelimiter));
            }
            else if (saveFileDialog.DefaultExt == "png") //Save a png image
            {
                //Get a bitmap containing the pattern.
                Bitmap bitmapToExport = new Bitmap(panel_staff.Width, panel_staff.Height);
                panel_staff.DrawToBitmap(bitmapToExport, new Rectangle(0, 0, panel_staff.Width, panel_staff.Height));

                //Save the bitmap
                bitmapToExport.Save(fileName, ImageFormat.Png);

            }
            else
            {
                MessageBox.Show("An error occured while saving incorrect file extension from saveFiledialog", "Error while saving");
            }
        }

        //Load pattern
        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            StrumPattern.LoadPattern(File.ReadAllText(openFileDialog.FileName), valueDelimiter);

            UpdateStrumDiagram();
            UpdateControls();


        }

        //Title changed
        private void textBox_title_TextChanged(object sender, EventArgs e)
        {
            StrumPattern.SetTitle(textBox_title.Text, valueDelimiter);
        }

        //Author changed
        private void textBox_author_TextChanged(object sender, EventArgs e)
        {
            StrumPattern.SetAuthor(textBox_author.Text, valueDelimiter);
        }

        //Help
        private void contentsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Strum Pattern maker is very easy to use. Just click on the arrows to\nshow/hide them, type the pattern's title and author name, then save!", "Help");
        }

        //About
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Strum Pattern Maker " + versionNumber + "\nby Jonathan Taylor", "About");
        }

    }

}
